﻿/*+===================================================================
File:      CGun.cpp

Summary:   Định nghĩa các phương thức của CGun.
===================================================================+*/

#include "Gun.h"
#include "Global.h"
#include "PlayState.h"
#include "FBullet.h"
#include "LBullet.h"
#include "EnemyBulletBig.h"
#include "BossOneBullet.h"
#include "EnemyDiverBullet.h"
#include "BossThreeBullet.h"
#include "BossTwoBullet.h"

// Mảng lưu các góc bắn của đạn S.
static float S_BULLETS_ANGLE[5] = { 0.0f, -10.0f, 10.0f, -20.0f, 20.0f };

// Mảng lưu các vận tốc x của đạn EnemyDiverBullet.
static float ENEMY_DIVER_BULLETS_ANGLE[5] = { 0.0f, -20.0f, 20.0f };

CGun::CGun(int curBulletType)
{
	SetCurBulletType(curBulletType);
}

CGun::CGun(int curBulletType, int maxBullets, int bulletPerShot)
{
	m_nCurBulletType = curBulletType;
	m_nMaxBullets = maxBullets;
	m_nBulletPerShot = bulletPerShot;
	m_nRemainBullets = m_nMaxBullets;
}

CGun::~CGun()
{

}

void CGun::SetCurBulletType(int bulletType)
{
	m_nCurBulletType = bulletType;

	switch (m_nCurBulletType)
	{
	case ID_R_BULLET:
	case ID_F_BULLET:
		m_nMaxBullets = 4;
		m_nBulletPerShot = 1;
		break;
	case ID_M_BULLET:
		m_nMaxBullets = 6;
		m_nBulletPerShot = 1;
		break;
	case ID_S_BULLET:
		m_nMaxBullets = 10;
		m_nBulletPerShot = 5;
		break;
	case ID_L_BULLET:
		m_nMaxBullets = 4;
		m_nBulletPerShot = 4;
		break;
	}

	m_nRemainBullets = m_nMaxBullets;
}

void CGun::SetBulletAngle(float angle)
{
	m_fBulletAngle = angle;
}

void CGun::SetCharaterDirectionX(int charaterDirectionX)
{
	m_nCharaterDirectionX = charaterDirectionX;
}

int CGun::GetCurBulletType()
{
	return m_nCurBulletType;
}

bool CGun::Fire(D3DXVECTOR2 pos)
{
	// Nếu là đạn L thì khi đạn còn trên màn hình vẫn có thể bắn.
	if (m_nCurBulletType == ID_L_BULLET)
	{
		CPlayState::s_billBullets.clear();
		m_nRemainBullets = m_nMaxBullets;
	}

	int bullets = m_nBulletPerShot < m_nRemainBullets ? m_nBulletPerShot : m_nRemainBullets;

	// Hết đạn.
	if (bullets == 0)
		return false;

	if (m_nCurBulletType == ID_S_BULLET)
	{
		for (int i = 0; i < bullets; i++)
		{
			int angle = m_fBulletAngle + S_BULLETS_ANGLE[i];
			CBullet* bullet = new CBullet(pos, i, m_nCurBulletType, angle);
			bullet->SetGun(this);
			CPlayState::s_billBullets.push_back(bullet);
			m_nRemainBullets--;
		}
	}
	else if (m_nCurBulletType == ID_F_BULLET)
	{
		for (int i = 0; i < bullets; i++)
		{
			CFBullet* bullet = new CFBullet(pos, i, m_nCurBulletType, m_fBulletAngle, m_nCharaterDirectionX);
			bullet->SetGun(this);
			CPlayState::s_billBullets.push_back(bullet);
			m_nRemainBullets--;
		}
	}
	else if (m_nCurBulletType == ID_L_BULLET)
	{
		CLBullet* preBullet = NULL;

		CLBullet** Lbullets = new CLBullet*[bullets];

		for (int i = 0; i < bullets; i++)
		{
			Lbullets[i] = new CLBullet(pos, i, m_nCurBulletType, m_fBulletAngle, m_nCharaterDirectionX);
			Lbullets[i]->SetGun(this);
		}

		for (int i = 0; i < bullets; i++)
		{
			if (i == 0)
			{
				Lbullets[i]->preBullet = NULL;
				Lbullets[i]->nextBullet = Lbullets[i + 1];
			}
			else if (i == 3)
			{
				Lbullets[i]->preBullet = Lbullets[i - 1];
				Lbullets[i]->nextBullet = NULL;
			}
			else
			{
				Lbullets[i]->preBullet = Lbullets[i - 1];
				Lbullets[i]->nextBullet = Lbullets[i + 1];;
			}
			
			CPlayState::s_billBullets.push_back(Lbullets[i]);
			m_nRemainBullets--;
		}
	}
	else if (m_nCurBulletType == ID_BOSS_ONE_BULLET)
	{
		for (int i = 0; i < bullets; i++)
		{
			CBossOneBullet* bullet = new CBossOneBullet(pos, i, m_nCurBulletType, m_fBulletAngle);
			bullet->SetGun(this);
			CPlayState::s_enemyBullets.push_back(bullet);
			m_nRemainBullets--;
		}
	}
	else if (m_nCurBulletType == ID_ENEMY_DIVER_BULLET)
	{
		for (int i = 0; i < bullets; i++)
		{
			CEnemyDiverBullet* bullet = new CEnemyDiverBullet(pos, i, m_nCurBulletType, ENEMY_DIVER_BULLETS_ANGLE[i]);
			bullet->SetGun(this);
			CPlayState::s_enemyBullets.push_back(bullet);
			m_nRemainBullets--;
		}
	}
	else if (m_nCurBulletType == ID_BOSS_THREE_BULLET)
	{
		for (int i = 0; i < bullets; i++)
		{
			CBossThreeBullet* bullet = new CBossThreeBullet(pos, i, m_nCurBulletType, m_fBulletAngle);
			bullet->SetGun(this);
			CPlayState::s_enemyBullets.push_back(bullet);
			m_nRemainBullets--;
		}
	}
	else if (m_nCurBulletType == ID_BOSS_TWO_BULLET)
	{
		for (int i = 0; i < bullets; i++)
		{
			CBossTwoBullet* bullet = new CBossTwoBullet(pos, i, m_nCurBulletType, m_fBulletAngle);
			bullet->SetGun(this);
			CPlayState::s_enemyBullets.push_back(bullet);
			m_nRemainBullets--;
		}
	}
	else  // Nếu không phải là các loại đạn đặc biệt.
	{
		for (int i = 0; i < bullets; i++)
		{
			CBullet* bullet = new CBullet(pos, i, m_nCurBulletType, m_fBulletAngle);
			bullet->SetGun(this);

			// Kiểm tra xem là đạn R, M của bill hay enemy để add vào các list tương ứng.
			if (m_nCurBulletType == ID_R_BULLET || m_nCurBulletType == ID_M_BULLET)
				CPlayState::s_billBullets.push_back(bullet);
			else
				CPlayState::s_enemyBullets.push_back(bullet);
			m_nRemainBullets--;
		}
	}

	return true;
}

void CGun::UpGun(int bulletItemType)
{
	switch (bulletItemType)
	{
		case ID_M_ITEM:
			SetCurBulletType(ID_M_BULLET);
			break;
		case ID_F_ITEM:
			SetCurBulletType(ID_F_BULLET);
			break;
		case ID_S_ITEM:
			SetCurBulletType(ID_S_BULLET);
			break;
		case ID_L_ITEM:
			SetCurBulletType(ID_L_BULLET);
			break;
		case ID_R_ITEM:
			SetCurBulletType(ID_R_BULLET);
			break;
	}
}

void CGun::ReloadBullet()
{
	m_nRemainBullets++;
}

bool CGun::IsFullBullets()
{
	return (m_nRemainBullets == m_nMaxBullets);
}

int CGun::GetRemainBullets()
{
	return m_nRemainBullets;
}

bool CGun::IsOutOfBullet()
{
	if (m_nRemainBullets == 0)
		return true;
	return false;
}
